<!DOCTYPE html>
<html>
    <script src="../../js-test-resources/js-test.js"></script>
    <meta http-equiv="Content-Security-Policy" content="connect-src 'none'">
<body>
<p id="description"></p>
<div id="console"></div>

<script>
description('Tests that isolated worlds can have XHRs that the page\'s CSP wouldn\'t allow.');

jsTestIsAsync = true;

var tests = [
    function() {
        debug('XHR from main world');
        xhr(true);
    },
    function() {
        debug('XHR from isolated world with unchanged CSP');
        testRunner.setIsolatedWorldInfo(1, window.origin, null);
        runTestInWorld(1, 'xhr', 'true');
    },
    function() {
        debug('XHR from isolated world with looser CSP');
        testRunner.setIsolatedWorldInfo(2, window.origin, 'connect-src *');
        runTestInWorld(2, 'xhr', 'false');
    },
    function() {
        debug('XHR from main world is not affected by the isolated world origin or CSP');
        xhr(true);
    }
];
var currentTest = 0;

// This test is meaningless without testRunner.
if (window.testRunner) {
    window.addEventListener(
        'message',
        function(event) {
            var message = JSON.parse(event.data);
            switch (message.type) {
                case 'test-done':
                    currentTest++;
                    if (currentTest == tests.length) {
                        testRunner.setIsolatedWorldInfo(1, null, null);
                        testRunner.setIsolatedWorldInfo(2, null, null);
                        finishJSTest();
                    }
                    else
                        tests[currentTest]();
                    break;
                case 'debug':
                    debug(message.message);
                    break;
                default:
                    testFailed('Unknown message: ' + event.data);
                    break;
            }
        },
        false);

    tests[0]();
} else {
    testFailed('Test depends on LayoutTestController and must be run by DRT');
}

function runTestInWorld(worldId, funcName, param)
{
    testRunner.evaluateScriptInIsolatedWorld(
        worldId, String(eval(funcName)) + "\n" + funcName + "(" + param + ");");
}

function xhr(shouldBlock)
{
    function debug(message) {
        window.postMessage(JSON.stringify({
                'type': 'debug',
                'message': message
            }),
            '*');
    }

    function signalComplete() {
        window.postMessage(JSON.stringify({'type': 'test-done'}), '*');
    }

    var xhr = new XMLHttpRequest();
    try {
        xhr.open('GET', '/security/isolatedWorld/resources/empty.html', true);
        xhr.onload = function(response) {
            if (shouldBlock)
                debug('FAIL: The request should have been disallowed');
            else
                debug('PASS: The request succeeded');
            signalComplete();
        };
        xhr.onerror = function() {
            if (shouldBlock)
                debug('PASS: The request was disallowed');
            else
                debug('FAIL: The request should have been allowed');
            signalComplete();
        }

        xhr.send();
    } catch (e) {
        debug('FAIL: XHR.open/send should not have thrown an exception');
        signalComplete();
    }
}

</script>

</body>
</html>
